#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define MAX_INPUT_SIZE 100

typedef struct Stack {
    int *items;
    int top;
    int size;
} Stack;

Stack* createStack(int size) {
    Stack* stack = (Stack*)malloc(sizeof(Stack));
    stack->items = (int*)malloc(size * sizeof(int));
    stack->top = -1;
    stack->size = size;
    return stack;
}

int isEmpty(Stack* stack) {
    return stack->top == -1;
}

int peek(Stack* stack) {
    return stack->items[stack->top];
}

void pop(Stack* stack) {
    stack->top--;
}

void push(Stack* stack, int value) {
    stack->items[++stack->top] = value;
}

int applyOperation(int a, int b, char op) {
    switch(op) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/': return b == 0 ? 0 : a / b;
    }
    return 0;
}

int precedence(char op) {
    if(op == '+' || op == '-') return 1;
    if(op == '*' || op == '/') return 2;
    return 0;
}

int evaluate(char* tokens) {
    Stack* values = createStack(MAX_INPUT_SIZE);
    Stack* ops = createStack(MAX_INPUT_SIZE);

    for(int i = 0; i < strlen(tokens); i++) {
        if(tokens[i] == ' ')
            continue;

        if(isdigit(tokens[i])) {
            int val = 0;
            while(i < strlen(tokens) && isdigit(tokens[i])) {
                val = (val * 10) + (tokens[i] - '0');
                i++;
            }
            push(values, val);
            i--;
        } else if(tokens[i] == '(') {
            push(ops, tokens[i]);
        } else if(tokens[i] == ')') {
            while(!isEmpty(ops) && peek(ops) != '(')
                push(values, applyOperation(pop(values), pop(values), pop(ops)));
            pop(ops);
        } else {
            while(!isEmpty(ops) && precedence(peek(ops)) >= precedence(tokens[i]))
                push(values, applyOperation(pop(values), pop(values), pop(ops)));

            push(ops, tokens[i]);
        }
    }

    while(!isEmpty(ops))
